﻿using System.Linq;
using StockManagement.Commands;
using System.Collections.ObjectModel;
using StockManagement.Helper;
using System.Windows;
using StockManagement.Model;
using System.Collections.Generic;

namespace StockManagement.ViewModels
{
    public class NewProductViewModel : ProductViewModel
    {
        ProductMaterialListViewModel _AllProdMaterialCollection = new ProductMaterialListViewModel();
        ObservableCollection<MaterialViewModel> _materialCollection;
        bool _bProdMatModified;

        DelegateCommand _addProductCommand;
        DelegateCommand _discardProductCommand;

        
        public event ProductAddedDelegate ProductAdded;

        public NewProductViewModel(ObservableCollection<MaterialViewModel> materialCollection)
            : base()
        {
            _materialCollection = materialCollection;
            _materialCollection.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(_allMaterialCollection_CollectionChanged);
            foreach (var item in _materialCollection)
                AddProductMaterial(item);

            ProductStatus = GetProductStatus();
            _addProductCommand = new DelegateCommand(ExecuteAddProductCommand, CanExecuteAddProductCommand);
            _discardProductCommand = new DelegateCommand(ExecuteDiscardProductCommand);
            PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(NewProductViewModel_PropertyChanged);
        }

        void _allMaterialCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
                    if (e.NewItems.Count > 0)
                    {
                        var coll = e.NewItems.Cast<MaterialViewModel>();
                        foreach (var item in coll)
                        {
                            AddProductMaterial(item);
                        }
                    }
                    break;
                case System.Collections.Specialized.NotifyCollectionChangedAction.Remove:
                    if (e.OldItems.Count > 0)
                    {
                        var coll = e.OldItems.Cast<MaterialViewModel>();
                        foreach (var item in coll)
                        {
                            var prodmat = _AllProdMaterialCollection.FirstOrDefault(p => p.MaterialID.Equals(item.MaterialID));
                            if (prodmat == null)
                                continue;

                            _AllProdMaterialCollection.Remove(prodmat);
                        }
                    }
                    break;
                default:
                    break;
            }
        }

        private void AddProductMaterial(MaterialViewModel item)
        {
            var itemProduct = new ProductMaterialViewModel(item.MaterialID, item.MaterialName, item.MaterialCode);
            itemProduct.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(itemProduct_PropertyChanged);
            _AllProdMaterialCollection.Add(itemProduct);
        }

        void itemProduct_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case "MaterialQuantity":
                case "IsSelected":
                    _bProdMatModified = true;
                    AddProductCommand.RaiseCanExecuteChanged();
                    break;
                default:
                    break;
            }
        }

        void NewProductViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case "ProductType":
                    ProductStatus = GetProductStatus();
                    break;
            }
            AddProductCommand.RaiseCanExecuteChanged();
        }

        private ProductStatus GetProductStatus()
        {
            switch (ProductType)
            {
                case EnumMaterialType.Trading:
                    return ProductStatus.Outward_ToBeDeliverd;
                case EnumMaterialType.Manufacturing:
                default:
                    return ProductStatus.Defined;
            }
        }
        public DelegateCommand AddProductCommand
        {
            get { return _addProductCommand; }
        }

        public DelegateCommand DiscardProductCommand
        {
            get { return _discardProductCommand; }
        }

        public ProductMaterialListViewModel AllProductMaterialCollection
        {
            get
            {
                return _AllProdMaterialCollection;
            }
        }

        private bool CanExecuteAddProductCommand(object parameter)
        {
            if (string.IsNullOrEmpty(ProductName.Trim())||
                string.IsNullOrEmpty(ProductCode.Trim())||
                _AllProdMaterialCollection.FirstOrDefault(p=>p.IsSelected && p.MaterialQuantity > 0) == null)
                return false;
            return true;
        }

        private void ExecuteAddProductCommand(object parameter)
        {
            var result = ShowConfirmationMessageBox("Do you want to add the new product?", "Add Product");
            if (!result)
                return;

            foreach (var item in _AllProdMaterialCollection)
            {
                if (!item.IsSelected)
                    continue;
                AddProductMaterialQuantity(item.Material);

                item.IsSelected = false;
                item.MaterialQuantity = 0;
            }

            ProductStatus = GetProductStatus();
            if (SaveProduct() && ProductAdded != null)
                ProductAdded();
            else
                ShowErrorMessageBox("Failed to add the product.", "Add Failed");

            AddProductCommand.RaiseCanExecuteChanged();
        }

        private void ExecuteDiscardProductCommand(object parameter)
        {
            var result = ShowConfirmationMessageBox("Do you want to discard the changes to new product?", "Discard");
            if(!result)
                return;

            DiscardProduct();
            foreach (var item in _AllProdMaterialCollection)
            {
                item.IsSelected = false;
                item.MaterialQuantity = 0;
            }

            AddProductCommand.RaiseCanExecuteChanged();
        }

    }
}
